package com.wiz.web.service.impl;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.gson.reflect.TypeToken;
import com.wiz.vo.criteria.PayCriteria;
import com.wiz.vo.to.PayOrderTO;
import com.wiz.vo.to.wjika.WjPayReqData;
import com.wiz.vo.to.wjika.WjPayResData;
import com.wiz.vo.type.PayMethodType;
import com.wiz.web.dao.mapper.WjPayMapper;
import com.wiz.web.manager.HttpManager;
import com.wiz.web.manager.HttpSSLManager;
import com.wiz.web.manager.fatory.WjiDataFactory;
import com.wiz.web.service.WjService;

@SuppressWarnings("all")
@Service("wjService")
public class WjServiceImpl extends BasicServiceImpl implements WjService {
	private transient final Logger log = LoggerFactory.getLogger(getClass());
	
	@Resource
	private WjiDataFactory wjiDataFactory;
	@Resource
	private WjPayMapper wjiPayMapper;
	@Resource
	private HttpManager httpManager;
	@Resource
	private HttpSSLManager httpSSLManager;
	
	@Override
	public String wjBarPay(String order,String hqId,String stationId,String wjiMerchantId) throws Exception{
		log.info("stationId="+stationId+" using wjiBarPay,params="+order);
		PayCriteria criteria = gson.fromJson(order, new TypeToken<PayCriteria>(){}.getType());
		criteria.setHqId(hqId);
		criteria.setStationId(stationId);
		criteria.setFuellingOrderId(criteria.getOutTradeNo());
		criteria.setOutTradeNo(createWjiOutTradeNo(stationId));
		criteria.setSubMchId(wjiMerchantId);
		WjPayReqData reqData = (WjPayReqData) wjiDataFactory.getDataByType(criteria,PayMethodType.BAR_PAY.getId());
		String response = httpManager.sendWjPost(WJ_IP,WJ_BAR_PAY, reqData);
		if(StringUtils.isBlank(response)){
			return getResponseFromReverse(criteria);
		}
		WjPayResData resData = gson.fromJson(response, new TypeToken<WjPayResData>(){}.getType());
		if(resData.getCode() == WJ_RETURN_CODE_SUCCESS){//支付成功
			criteria.setTransactionId(resData.getVal().getPaymentno());
			criteria.setResult(response);
			criteria.setPayTime(resData.getVal().getDate().replaceAll("/","-"));
			criteria.setStatus(1);
			wjiPayMapper.insertWjPayOrder(criteria);
			PayOrderTO orderTO = new PayOrderTO();
			orderTO.setFuellingOrderId(criteria.getFuellingOrderId());
			orderTO.setPayOrderId(criteria.getOutTradeNo());
			orderTO.setRefOrderId(resData.getVal().getPaymentno());
			return returnResult(CODE_OK, STRING_OK, orderTO);
		}else if(resData.getCode() == WJ_RETURN_CODE_PROCCESS){//正在处理
			int each = 0;
			WjPayResData responseData = null;
			Thread.currentThread().sleep(2000);
			while(each<4){//30秒后
				criteria.setTransactionId(resData.getVal().getPaymentno());
				response = queryWjOrder(criteria);
				responseData = gson.fromJson(response, new TypeToken<WjPayResData>(){}.getType());
				if(resData.getCode() == WJ_RETURN_CODE_SUCCESS){
					if(responseData.getVal().getStatus() == WJ_TRADE_CODE_SUCCESS){
						criteria.setResult(response);
						criteria.setPayTime(responseData.getVal().getDate().replaceAll("/","-"));
						criteria.setStatus(1);
						wjiPayMapper.insertWjPayOrder(criteria);
						PayOrderTO orderTO = new PayOrderTO();
						orderTO.setFuellingOrderId(criteria.getFuellingOrderId());
						orderTO.setPayOrderId(criteria.getOutTradeNo());
						orderTO.setRefOrderId(responseData.getVal().getPaymentno());
						return returnResult(CODE_OK, STRING_OK, orderTO);
					}else if(responseData.getVal().getStatus() == WJ_TRADE_CODE_UNPAID){//非用户支付中 状态下，直接返回结果
	//						continue;
					}else{
						log.warn("stationId="+stationId+" wjBarPay fail,response="+response);
						return RESPONSE_WJ_FAILED;
					}
				}
				if(each==3){
					log.info(criteria.getOutTradeNo()+" will Reverse order in WJ");
					return getResponseFromReverse(criteria);
				}
				each++;
				Thread.currentThread().sleep(10000);
			}
		}
//		log.warn("stationId="+stationId+"pay fail,response="+resData.getCode()+" || "+resData.getMsg()
//				+",reverseWxOrder will begin after 16s");
//		Thread.currentThread().sleep(16000);
//		criteria.setTransactionId(criteria.getOutTradeNo());
		log.warn("stationId="+stationId+" wjBarPay fail,response="+response);
		return returnResult(67999, resData.getMsg(), null);
	}

	/**
	 * 查询万集订单
	 * @param criteria
	 * @return
	 */
	private String queryWjOrder(PayCriteria criteria){
		WjPayReqData payData = (WjPayReqData) wjiDataFactory.getDataByType(criteria,PayMethodType.QUERY.getId());
		return httpManager.sendWjPost(WJ_IP,WJ_BAR_ORDER_SEARCH, payData);
	}
	
	/**
	 * 撤销万集订单
	 * @param criteria
	 * @return
	 */
	private WjPayResData reverseWxOrder(PayCriteria criteria){
		WjPayReqData payData = (WjPayReqData) wjiDataFactory.getDataByType(criteria,PayMethodType.REVERSE.getId());
		String response = httpManager.sendWjPost(WJ_IP,WJ_BAR_REVERSE, payData);
		return gson.fromJson(response, new TypeToken<WjPayResData>(){}.getType());
	}
	
	/**
	 * 解析撤销返回结果
	 * @param criteria
	 * @return
	 */
	private String getResponseFromReverse(PayCriteria criteria){
		WjPayResData responseDataReverse = reverseWxOrder(criteria);
		log.info("WJI responseDataReverse="+responseDataReverse.toString());
		if(responseDataReverse.getCode() == WJ_RETURN_CODE_SUCCESS){//撤销成功
			return RESPONSE_WJ_FAILED;
		}else {//查询一次
			String response = queryWjOrder(criteria);
			WjPayResData responseData = responseData = gson.fromJson(response, new TypeToken<WjPayResData>(){}.getType());
			if(responseData.getCode() == WJ_RETURN_CODE_SUCCESS){
				if(responseData.getVal().getStatus() == WJ_TRADE_CODE_SUCCESS){
					criteria.setResult(response);
					criteria.setPayTime(responseData.getVal().getDate().replaceAll("/","-"));
					criteria.setStatus(1);
					wjiPayMapper.insertWjPayOrder(criteria);
					PayOrderTO orderTO = new PayOrderTO();
					orderTO.setFuellingOrderId(criteria.getFuellingOrderId());
					orderTO.setPayOrderId(criteria.getOutTradeNo());
					orderTO.setRefOrderId(responseData.getVal().getPaymentno());
					return returnResult(CODE_OK, STRING_OK, orderTO);
				}
			}
			log.warn(" wjReverse fail,response="+response);
		}
		return RESPONSE_WJ_FAILED;
	}
	
	/**
	 * 支付订单号
	 * @param stationId
	 * @return
	 */
	private String createWjiOutTradeNo(String stationId){
		return "WJ"+stationId+System.currentTimeMillis()+getRandom(5);
	}
}
